home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / mpmod160.zip / SOURCE.ZIP / Z-RX.C < prev    next >
C/C++ Source or Header  |  1994-01-01  |  18KB  |  508 lines

  1. /*--------------------------------------------------------------------------*/
  2. /* The receive part of the Zmodem protocol.                                 */
  3. /*                                                                           */
  4. /* (C) Copyright M. Jose, 1990 ->                                            */
  5. /* See MPMODEM.DOC for more details about the usage of this source in your   */
  6. /* programs.                                                                 */
  7. /* Written by Mark Jose, Oct-Nov, 1990.                                      */
  8. /*---------------------------------------------------------------------------*/
  9. [...]
  10.  
  11. #include "compress.h"
  12.  
  13. /*--------------------------------------------------------------------------*/
  14. /* Local function prototypes                                                */
  15. /*--------------------------------------------------------------------------*/
  16. static int pascal ReceiveData(BYTE *,int);
  17.           /* If you don't have a seperate routine to handle the receipt of  */
  18.           /* packets with CRC-16, then you must do so in order to implement */
  19.           /* compression.                                                   */
  20.           /*                                                                */
  21.           /* Some people implement Zmodem without the ability to run it in  */
  22.           /* CRC-16 mode because it will always default to the safer CRC-32 */
  23.           /* mode. This is fine, but when you want to use it over quite     */
  24.           /* secure lines, CRC-16 is quite adequate.                        */
  25.  
  26. static int pascal ReceiveData16(BYTE *, int);
  27. static int pascal ReceiveData32(BYTE *, int);
  28. [...]
  29.  
  30.  
  31. /*
  32.  RECEIVE DATA
  33.  This module decides what type of packet routine we should call. The type
  34.  of packet was determined when we went into Z_GetHeader (in ZMISC.C) and
  35.  set the flag of RxType.
  36.    RxType   Transmission process
  37.    --------------------------------------------------------------------
  38.       0        Normal Zmodem transmission using CRC-16.
  39.       1        CRC-32 binary transfer.
  40.       2        (Not used - next release)
  41.       3        CRC-32 binary transfer with compression (when needed)
  42.       4        CRC-16 binary transfer with compression (when needed)
  43.  
  44. */
  45. static int pascal ReceiveData(BYTE *buf, int length)
  46. {
  47.     static int stat;
  48.  
  49.     switch (RxType) {
  50. /*
  51. Here we have two new options, for CRC-16 and CRC-32 compressed packets.
  52. In order to use this method, you must call the routines with CompBuff (the
  53. compression buffer which MUST be the same size as your normal TX/RX buffer).
  54. When the packet is received, the frame end indicator will decide whether
  55. the packet just received is a compressed packet. If it is, then the
  56. decompression routine is called and the result is that the data in CompBuff
  57. is expanded into "buf" (which is the buffer passed to this routine).
  58. If the packet is not compressed, then a quick memcpy is done to copy it
  59. from CompBuff to "buf".
  60. */
  61.  
  62.        case 4:      /* Possibly a compressed CRC-16 packet */
  63.           Compressed = 0;
  64.           stat = ReceiveData16(CompBuff, length);
  65.           break;
  66.        case 3:      /* Possibly a compressed CRC-32 packet */
  67.           Compressed = 0;
  68.           stat = ReceiveData32(CompBuff, length);
  69.           break;
  70.        default:     /* Well there shouldn't be any other type! */
  71.        case 2:      /* Not used */
  72.           return ZERROR;
  73.        case 1:      /* CRC-32 plain binary */
  74.           return (ReceiveData32(buf, length));
  75.        case 0:     /* CRC-16 plain binary */
  76.           return (ReceiveData16(buf, length));
  77.     }
  78.         /* The only stuff to get here is compressed packets! */
  79. /*
  80. Now, depending on the status of the "Compressed" flag, we either decompress
  81. the data or do a straight copy.
  82. */
  83.     if (Compressed) {
  84.        BlockSize = DeCompress(CompBuff, buf, BlockSize);
  85.     } else {
  86.        memcpy(buf, CompBuff, BlockSize);
  87.     }
  88.  
  89.     return stat;
  90.  
  91. }
  92.  
  93. /*
  94. In some cases, you may have to create this routine by splitting it from the
  95. original ReceiveData() routine.
  96. */
  97.  
  98. /*
  99.  RZ_ReceiveData16
  100.   Handles 16 bit CRC data packets
  101. */
  102. static int pascal ReceiveData16(BYTE *buf, int length)
  103. {
  104.     register int c;
  105.     static char *endpos;
  106.     static int d;
  107.     static WORD crc;
  108.  
  109.     crc = BlockSize = 0;
  110.     endpos = (char *)buf + length;
  111.  
  112.     while ((char *)buf <= endpos) {
  113.        if ((c = GetZDLE()) & ~0xFF) {
  114. CRCError:
  115.           switch (c) {
  116. /*
  117. This bit of code determines whether the transmission was done using
  118. compression. If any of the following frame ends were received, they
  119. will set the "Compressed" flag which will notify the ReceiveData()
  120. routine.
  121. */
  122.              case GOTCRCE_C:                    /* ---** Add this **--- */
  123.              case GOTCRCG_C:                    /* ---** Add this **--- */
  124.              case GOTCRCQ_C:                    /* ---** Add this **--- */
  125.              case GOTCRCW_C:                    /* ---** Add this **--- */
  126.                 Compressed = 1;                 /* ---** Add this **--- */
  127.                 /* Fall through to normal process of CRC */
  128.              case GOTCRCE:
  129.              case GOTCRCG:
  130.              case GOTCRCQ:
  131.              case GOTCRCW:  /* CRCs */
  132.                 d = c;
  133.                 crc = Z_UpdateCRC( (c & 0xFF), crc);
  134.                 if ((c = GetZDLE()) & ~0xFF)
  135.                    goto CRCError;
  136.                 crc = Z_UpdateCRC(c, crc);
  137.                 if ((c = GetZDLE()) & ~0xFF)
  138.                    goto CRCError;
  139.                 crc = Z_UpdateCRC(c, crc);
  140.                 if (crc & 0xFFFF) {
  141.                     /* Report a CRC error to main routine */
  142.                    return ZERROR;
  143.                 }
  144.                 BlockSize = length - (int ) (endpos - (char *) buf);
  145.                 return d;
  146.              case GOTCAN:   /* Cancel  */
  147.                 return ZCAN;
  148.              case ZTIMEOUT:  /* Timeout  */
  149.                 return c;
  150.              case RCDO:     /* No carrier */
  151.                 return c;
  152.              default:       /* What happened?   */
  153.                 return c;
  154.           }
  155.        }
  156.        *buf++ = (BYTE ) c;
  157.        crc = Z_UpdateCRC(c, crc);
  158.     }
  159.     return ZERROR;
  160. }
  161.  
  162.  
  163.  
  164. /*
  165.  ReceiveData32
  166.   Handles 32 bit CRC data packets
  167. */
  168. static int pascal ReceiveData32(BYTE *buf, int length)
  169. {
  170.     register int c, n;
  171.     static int d;
  172.     static char *endpos;
  173.     static ULONG crc;
  174.  
  175.     BlockSize = 0;
  176.     crc = 0xFFFFFFFFL;
  177.     endpos = (char *)buf + length;
  178.  
  179.     while ((char *)buf <= endpos) {
  180.        if ((c = GetZDLE()) & ~0xFF) {
  181. CRCError:
  182.           switch (c) {
  183. /*
  184. This bit of code determines whether the transmission was done using
  185. compression. If any of the following frame ends were received, they
  186. will set the "Compressed" flag which will notify the ReceiveData()
  187. routine.
  188. */
  189.              case GOTCRCE_C:                    /* ---** Add this **--- */
  190.              case GOTCRCG_C:                    /* ---** Add this **--- */
  191.              case GOTCRCQ_C:                    /* ---** Add this **--- */
  192.              case GOTCRCW_C:                    /* ---** Add this **--- */
  193.                 Compressed = 1;                 /* ---** Add this **--- */
  194.                 /* Fall through to normal process of CRC */
  195.              case GOTCRCE:
  196.              case GOTCRCG:
  197.              case GOTCRCQ:
  198.              case GOTCRCW:
  199.                 d = c;
  200.                 c &= 0377;
  201.                 crc = Z_UpdateCRC32(c, crc);
  202.                 for (n = 0; n < 4; n++) {
  203.                    if ((c = GetZDLE()) & ~0xFF)
  204.                       goto CRCError;
  205.                    crc = Z_UpdateCRC32(c, crc);
  206.                 }
  207.                 if (crc != 0xDEBB20E3) {
  208.                     /* Report a CRC error to main routine */
  209.                    return ZERROR;
  210.                 }
  211.                 BlockSize = length - (int) (endpos - (char *)buf);
  212.                 return(d);
  213.              case GOTCAN:
  214.                 return ZCAN;
  215.              case ZTIMEOUT:
  216.                 return c;
  217.              case RCDO:
  218.